package com.test.config;

import com.alibaba.fastjson.JSONObject;
import com.test.dto.R;
import org.springframework.http.HttpStatus;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * @author wangXiaoMing
 * @date 2021/11/22 16:04
 */
@RestControllerAdvice
public class ControllerAdvice {

    /**
     * 拦截JSON参数校验
     */
    @ResponseStatus(HttpStatus.OK)
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Map<String, String> bindException(MethodArgumentNotValidException e) {

        BindingResult bindingResult = e.getBindingResult();

        String msg = Objects.requireNonNull(bindingResult.getFieldError()).getDefaultMessage();

//        log.error("参数校验异常拦截：{}", msg);

        Map<String, String> result = new HashMap<>();

        result.put("code", "1001");
        result.put("msg", msg);
        result.put("data", null);

        return result;
    }

    /**
     * 拦截类型不匹配
     */
    @ResponseStatus(HttpStatus.OK)
    @ExceptionHandler(HttpMessageNotReadableException.class)
    public R<?> bindException(HttpMessageNotReadableException e) {

        return R.paramErr("参数中有不符合目标格式的");


//        System.out.println("JSONObject.toJSONString(e) = " + JSONObject.toJSONString(e));

// 打印堆栈信息
//        log.error(ThrowableUtil.getStackTrace(e));
//        String erroMessage = null;
//        Throwable cause = e.getCause();
//        if (cause instanceof JsonMappingException) {
//            List<JsonMappingException.Reference> list = ((JsonMappingException) cause).getPath();
//            for (JsonMappingException.Reference r : list) {
//                Object object = r.getFrom();
//                Class<?> c = object.getClass();
//                String fieldName = r.getFieldName();
//                Field field;
//                try {
//                    field = c.getDeclaredField(fieldName);
//                    JsonFormatVaild jsonFormatVaild = field.getDeclaredAnnotation(JsonFormatVaild.class);
//                    erroMessage = jsonFormatVaild.message();
//                } catch (NoSuchFieldException noSuchFieldException) {
//                    noSuchFieldException.printStackTrace();
//                }
//                if (erroMessage != null) {
//                    break;
//                }
//            }
//        }



//
//        String defaultMsg = "该接口中有参数不符合目标格式";
//
//        String message = e.getMessage();
//        if (message == null) {
//            return R.paramErr(defaultMsg);
//        }
//
//        // 字符串在202处
//        // 数字在203处
//        // 此处取150即可
//        int fromIndex = 150;

        /// TODO
        // 可能直接参数和内部对象的方式提醒不一样
        // 可能是因为引入fastjson的原因

        // localhost/simple/test

        // {
        //    "num": "324s",
        //    "str":2
        //}

        // {
        //    "code": "1001",
        //    "msg": "内容: (PushbackInputStream) 不符合字段: [\"num\"]",
        //    "data": null
        //}

//
//        try {
//
//            String key = message.substring(message.lastIndexOf("[\"") + 2, message.lastIndexOf("\"]"));
//
//            String value = message.substring(message.indexOf("(", fromIndex) + 1, message.indexOf(")", fromIndex));
//
//            if (StringUtils.isEmpty(key) || StringUtils.isEmpty(value)) {
//                throw new Exception("字段内容取出为空");
//            }
//            return R.paramErr("内容: (" + value + ") 不符合字段: [\"" + key + "\"]");
//        } catch (Exception exception) {
//            return R.paramErr(defaultMsg);
//        }
    }

//    /**
//     * 可以处理全局异常，慎用
//     */
//    @ResponseStatus(HttpStatus.OK)
//    @ExceptionHandler(Exception.class)
//    public Object allException(Exception exception) {
//
//        return exception.getMessage();
//    }
}
